"""
LAN对讲机 - 完整构建脚本
一键构建主程序和安装程序
"""
import os
import sys
import shutil
import subprocess


def print_banner():
    """打印横幅"""
    print("\n")
    print("╔══════════════════════════════════════════════════════════╗")
    print("║       LAN对讲机 - 完整构建工具                          ║")
    print("║       主程序 + 安装程序 一键构建                         ║")
    print("╚══════════════════════════════════════════════════════════╝")
    print()


def print_step(step_num, total_steps, title):
    """打印步骤标题"""
    print("\n" + "=" * 60)
    print(f"步骤 {step_num}/{total_steps}: {title}")
    print("=" * 60)


def clean_previous_builds():
    """清理之前的构建"""
    print_step(1, 4, "清理之前的构建")
    
    dirs_to_clean = ['dist', 'build', 'installer_package']
    files_to_clean = ['LAN对讲机_Setup.spec']
    
    for dir_name in dirs_to_clean:
        if os.path.exists(dir_name):
            print(f"[清理] 删除目录: {dir_name}")
            shutil.rmtree(dir_name)
    
    for file_name in files_to_clean:
        if os.path.exists(file_name):
            print(f"[清理] 删除文件: {file_name}")
            os.remove(file_name)
    
    print("[成功] 清理完成！\n")


def build_main_app():
    """构建主程序（目录版）"""
    print_step(2, 4, "构建主程序（目录版）")
    
    # 检查spec文件
    spec_file = 'walkietalkie_dir.spec'
    if not os.path.exists(spec_file):
        print(f"[错误] 未找到 {spec_file}")
        return False
    
    print(f"[信息] 使用配置文件: {spec_file}")
    print("[信息] 开始打包主程序...")
    print()
    
    # 执行PyInstaller
    cmd = ['pyinstaller', spec_file, '--clean', '--noconfirm']
    
    try:
        result = subprocess.run(cmd, check=True)
        
        # 检查输出
        app_dir = os.path.join('dist', 'LAN对讲机')
        if os.path.exists(app_dir):
            exe_file = os.path.join(app_dir, 'LAN对讲机.exe')
            if os.path.exists(exe_file):
                file_size = os.path.getsize(exe_file) / (1024 * 1024)
                print(f"\n[成功] 主程序构建完成！")
                print(f"   位置: {app_dir}")
                print(f"   主程序: LAN对讲机.exe ({file_size:.2f} MB)")
                
                # 统计文件数量
                total_files = sum([len(files) for _, _, files in os.walk(app_dir)])
                print(f"   总文件数: {total_files}")
                return True
            else:
                print(f"[错误] 未找到主程序: {exe_file}")
                return False
        else:
            print(f"[错误] 未找到输出目录: {app_dir}")
            return False
            
    except subprocess.CalledProcessError as e:
        print(f"\n[错误] 构建失败: {e}")
        return False
    except FileNotFoundError:
        print("\n[错误] 未找到 PyInstaller，请先安装:")
        print("       pip install pyinstaller")
        return False


def build_uninstaller():
    """构建卸载程序"""
    print_step(3, 4, "构建卸载程序")
    
    # 检查spec文件
    spec_file = 'uninstall.spec'
    if not os.path.exists(spec_file):
        print(f"[错误] 未找到 {spec_file}")
        return False
    
    if not os.path.exists('uninstall_app.py'):
        print("[错误] 未找到 uninstall_app.py")
        return False
    
    print(f"[信息] 使用配置文件: {spec_file}")
    print("[信息] 开始打包卸载程序...")
    print()
    
    # 执行PyInstaller
    cmd = ['pyinstaller', spec_file, '--clean', '--noconfirm']
    
    try:
        result = subprocess.run(cmd, check=True)
        
        # 检查输出
        uninstall_exe = os.path.join('dist', 'Uninstall.exe')
        if os.path.exists(uninstall_exe):
            file_size = os.path.getsize(uninstall_exe) / (1024 * 1024)
            print(f"\n[成功] 卸载程序构建完成！")
            print(f"   位置: {uninstall_exe}")
            print(f"   大小: {file_size:.2f} MB")
            return True
        else:
            print(f"[错误] 未找到卸载程序: {uninstall_exe}")
            return False
            
    except subprocess.CalledProcessError as e:
        print(f"\n[错误] 构建失败: {e}")
        return False
    except FileNotFoundError:
        print("\n[错误] 未找到 PyInstaller，请先安装:")
        print("       pip install pyinstaller")
        return False


def build_installer():
    """构建安装程序"""
    print_step(4, 4, "构建安装程序")
    
    # 1. 检查必要文件
    print("[检查] 验证必要文件...")
    
    app_dir = os.path.join('dist', 'LAN对讲机')
    if not os.path.exists(app_dir):
        print(f"[错误] 未找到主程序目录: {app_dir}")
        print("       请先完成主程序构建")
        return False
    print(f"[OK] 主程序目录: {app_dir}")
    
    if not os.path.exists('installer_wizard.py'):
        print("[错误] 未找到 installer_wizard.py")
        return False
    print("[OK] 安装向导脚本: installer_wizard.py")
    
    if os.path.exists('icon.ico'):
        print("[OK] 图标文件: icon.ico")
    else:
        print("[警告] 未找到 icon.ico，将使用默认图标")
    
    # 2. 创建临时安装包
    print("\n[准备] 创建安装包...")
    temp_dir = 'installer_package'
    if os.path.exists(temp_dir):
        shutil.rmtree(temp_dir)
    os.makedirs(temp_dir)
    
    # 创建 app_files 子目录
    app_files_dir = os.path.join(temp_dir, 'app_files')
    os.makedirs(app_files_dir)
    
    # 复制主程序所有文件
    print("[复制] 主程序文件到安装包...")
    for item in os.listdir(app_dir):
        src_path = os.path.join(app_dir, item)
        dst_path = os.path.join(app_files_dir, item)
        
        if os.path.isdir(src_path):
            shutil.copytree(src_path, dst_path)
            print(f"   [目录] {item}")
        else:
            shutil.copy2(src_path, dst_path)
            print(f"   [文件] {item}")
    
    # 复制卸载程序
    uninstall_exe = os.path.join('dist', 'Uninstall.exe')
    if os.path.exists(uninstall_exe):
        shutil.copy2(uninstall_exe, app_files_dir)
        print("   [+] Uninstall.exe")
    else:
        print("   [警告] 未找到 Uninstall.exe")
    
    # 复制安装向导
    shutil.copy2('installer_wizard.py', temp_dir)
    print("   [+] installer_wizard.py")
    
    # 复制图标
    if os.path.exists('icon.ico'):
        shutil.copy2('icon.ico', temp_dir)
        print("   [+] icon.ico")
    
    # 3. 打包安装程序
    print("\n[打包] 生成安装程序 exe...")
    
    # 获取绝对路径（PyInstaller 在某些情况下需要绝对路径）
    abs_temp_dir = os.path.abspath(temp_dir)
    abs_app_files = os.path.join(abs_temp_dir, 'app_files')
    abs_icon = os.path.join(abs_temp_dir, 'icon.ico')
    abs_installer_script = os.path.join(abs_temp_dir, 'installer_wizard.py')
    
    cmd = [
        'pyinstaller',
        '--onefile',
        '--windowed',
        '--name=LAN对讲机_Setup',
        '--clean',
        '--noconfirm',
    ]
    
    if os.path.exists('icon.ico'):
        cmd.append('--icon=icon.ico')
    
    # 添加数据文件（使用绝对路径）
    cmd.append(f'--add-data={abs_app_files};app_files')
    
    if os.path.exists(abs_icon):
        cmd.append(f'--add-data={abs_icon};.')
    
    cmd.append(abs_installer_script)
    
    print(f"\n执行命令: {' '.join(cmd)}\n")
    
    try:
        result = subprocess.run(cmd, check=True)
        
        # 检查生成的安装程序
        setup_exe = os.path.join('dist', 'LAN对讲机_Setup.exe')
        if os.path.exists(setup_exe):
            file_size = os.path.getsize(setup_exe) / (1024 * 1024)
            print(f"\n[成功] 安装程序构建完成！")
            print(f"   位置: {setup_exe}")
            print(f"   大小: {file_size:.2f} MB")
            
            # 4. 清理临时文件
            print("\n[清理] 临时文件...")
            if os.path.exists(temp_dir):
                shutil.rmtree(temp_dir)
                print(f"   删除: {temp_dir}")
            
            spec_file = 'LAN对讲机_Setup.spec'
            if os.path.exists(spec_file):
                os.remove(spec_file)
                print(f"   删除: {spec_file}")
            
            if os.path.exists('build'):
                shutil.rmtree('build')
                print(f"   删除: build")
            
            return True
        else:
            print(f"[错误] 未找到安装程序: {setup_exe}")
            return False
            
    except subprocess.CalledProcessError as e:
        print(f"\n[错误] 打包失败: {e}")
        return False
    except FileNotFoundError:
        print("\n[错误] 未找到 PyInstaller")
        return False


def print_summary():
    """打印构建摘要"""
    print("\n" + "=" * 60)
    print("构建完成摘要")
    print("=" * 60)
    
    print("\n生成的文件：")
    
    # 主程序目录
    app_dir = os.path.join('dist', 'LAN对讲机')
    if os.path.exists(app_dir):
        print(f"\n1. 主程序（目录版）")
        print(f"   位置: {app_dir}\\")
        print(f"   主文件: LAN对讲机.exe")
        print(f"   用途: 开发测试、直接运行")
    
    # 安装程序
    setup_exe = os.path.join('dist', 'LAN对讲机_Setup.exe')
    if os.path.exists(setup_exe):
        file_size = os.path.getsize(setup_exe) / (1024 * 1024)
        print(f"\n2. 安装程序")
        print(f"   位置: {setup_exe}")
        print(f"   大小: {file_size:.2f} MB")
        print(f"   用途: 分发给用户安装")
    
    print("\n安装程序特性：")
    print("  [+] 包含所有依赖，无需安装Python")
    print("  [+] 专业安装向导界面")
    print("  [+] 自定义安装路径")
    print("  [+] 自动创建快捷方式")
    print("  [+] 支持开机自启动")
    print("  [+] 完整的卸载功能")
    print("  [+] 系统注册（添加/删除程序）")
    print("  [+] 房主重连双向通知机制")
    print("  [+] 成员列表自动恢复")
    print("  [+] 开机启动自动最小化")
    
    print("\n使用建议：")
    print("  > 测试时：直接运行 dist\\LAN对讲机\\LAN对讲机.exe")
    print("  > 分发时：将 dist\\LAN对讲机_Setup.exe 发送给用户")
    
    print("\n" + "=" * 60)


def main():
    """主函数"""
    print_banner()
    
    try:
        # 步骤1: 清理
        clean_previous_builds()
        
        # 步骤2: 构建主程序
        if not build_main_app():
            print("\n[失败] 主程序构建失败，停止构建")
            sys.exit(1)
        
        # 步骤3: 构建卸载程序
        if not build_uninstaller():
            print("\n[失败] 卸载程序构建失败，停止构建")
            sys.exit(1)
        
        # 步骤4: 构建安装程序
        if not build_installer():
            print("\n[失败] 安装程序构建失败")
            sys.exit(1)
        
        # 打印摘要
        print_summary()
        
        print("\n[完成] 所有构建任务已完成！")
        print()
        
    except KeyboardInterrupt:
        print("\n\n[取消] 用户中断了构建过程")
        sys.exit(0)
    except Exception as e:
        print(f"\n[错误] 发生异常: {e}")
        import traceback
        traceback.print_exc()
        sys.exit(1)


if __name__ == "__main__":
    main()
